﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CrmContacto.Contracts.Externos;
using CrmContacto.CrmWs.ServiceReferenceApiAuth;
using Web.Framework.Translate;
using CrmContacto.Contracts.Services;
using Web.Framework.Svc;
using CrmContacto.Contracts;
using CrmContacto.Data;
using Web.Framework.Mapper;
using System.Configuration;
using CrmContacto.Contracts.Enums;

namespace CrmContacto.Services
{
    public class CrmExternosService : ICrmExterno
    {
        private const int ApplicationId = 5;

        private const string PermisoString = "EXTERNO_EDICION_CONTACTO";

        public int GuardarContactoExtendido(int Id, string UserName, string Password, int EmpresaId, string TipoDocumento, decimal? NroDocumento, string Email, string Nombre, string Apellido, short? CumpleDia, short? CumpleMes, short? CumpleAnio, string Nacionalidad, string Provincia, string Domicilio, string CodigoPostal, string Telefono, List<string> Categorias, bool DeseaRecibirEmails, int? Sexo, int? CantidadHijos, int? EdadHijoMenor, out bool GuardadoOk,  out  List<string> mensajes)
        {
            ContactoE contacto = new ContactoE();
           
            // Asigno los valores de los parametros
            contacto.Id = Id;
            contacto.UserName = UserName;
            contacto.Password = Password;
            contacto.EmpresaId = EmpresaId;
            contacto.TipoDocumento = TipoDocumento;
            contacto.NroDocumento = NroDocumento;
            contacto.Email = Email;
            contacto.Nombre = Nombre;
            contacto.Apellido = Apellido;
            contacto.CumpleDia = CumpleDia;
            contacto.CumpleMes = CumpleMes;
            contacto.CumpleAnio = CumpleAnio;
            contacto.Nacionalidad = Nacionalidad;
            contacto.Provincia = Provincia;
            contacto.Domicilio = Domicilio;
            contacto.CodigoPostal = CodigoPostal;
            contacto.Telefono = Telefono;
            if (Categorias == null)
            {
                Categorias = new List<string>();
            }

            contacto.Categorias = Categorias;
            contacto.DeseaRecibirEmails = DeseaRecibirEmails;
            contacto.Sexo = Sexo;
            contacto.CantidadHijos = CantidadHijos;
            contacto.EdadHijoMenor = EdadHijoMenor;            

            // Guardo el objeto contacto
            contacto = GuardarContacto(contacto);
            GuardadoOk = contacto.GuardadoOk;
            mensajes = contacto.Mensajes;
            return contacto.Id;
        }

        public ContactoE GuardarContacto(ContactoE contactoE)
        {            
            // Primero valido al usuario
            int empresaId = contactoE.EmpresaId;
            string userName = contactoE.UserName;
            string password = contactoE.Password;

            contactoE.GuardadoOk = false;
            if(contactoE.Mensajes == null)
            {
                contactoE.Mensajes = new List<string>();
            }
            
            contactoE.Mensajes.Clear();

            AuthApiClient authClient = new AuthApiClient();
            bool isUserAuthenticated = authClient.ValidateUser(ApplicationId, empresaId, userName, password);
            bool isAuthorized = false;
            if (!isUserAuthenticated)
            {
                contactoE.Mensajes.Add(LocalizationProvider.Instance["ServicioExterno.Validacion.NoAutenticado"]);
            }
            else
            {
                // Valido la autorización
                List<string> operationsForUser = authClient.GetOperationsForUser(ApplicationId, empresaId, userName);
                isAuthorized = operationsForUser.Where(o => o == PermisoString).Count() > 0;

                if (!isAuthorized)
                {
                    contactoE.Mensajes.Add(LocalizationProvider.Instance["ServicioExterno.Validacion.NoAutorizado"]);
                }
            }
            
            // Si está autorizado, lo guardo (nuevo o actualizado)
            if (isUserAuthenticated && isAuthorized)
            {
                ICrmContactoAdminService crmService = new CrmContactoAdminService();

                ServiceOptions options = new ServiceOptions();
                options.UserName = userName;
                
                try
                {
                    Cliente customer = GetClienteFromContactoE(contactoE);
                    customer = crmService.SaveCustomer(options, customer);
                    contactoE.Id = customer.Id;
                    contactoE.GuardadoOk = true;
                }
                catch (Exception ex)
                {
                    contactoE.Mensajes.Add(ex.Message);
                }
            }

            return contactoE;
        }

        private Cliente GetClienteFromContactoE(ContactoE contactoE)
        {
            string paisPorDefecto = ConfigurationManager.AppSettings["LenguajePorDefecto"];
            Cliente cliente = new Cliente();
            cliente.Categorias = new List<MaestroBase>();

            using (CrmContactoEntities ctx = new CrmContactoEntities())
            {
                int empresaId = contactoE.EmpresaId;

                EntityMapper.Map(contactoE, cliente, "Categorias", "Bitacora");
                cliente.Dni = contactoE.NroDocumento;

                // origen
                cliente.OrigenId = (int)TipoContactoOrigen.WebServiceExterno;
                
                // Tipo de documento
                var tipoDocumento = ctx.DbTipoDocumentoes.Where(t => t.Nombre == contactoE.TipoDocumento).SingleOrDefault();
                if (tipoDocumento != null)
                {
                    cliente.TipoDocumentoId = tipoDocumento.Id;
                }

                // Nacionalidad
                if (!String.IsNullOrEmpty(contactoE.Nacionalidad))
                {
                    var traduccionPais = ctx.DbPalabrasClaveAplicacionLenguajes.Where(p => p.LenguajeId == paisPorDefecto && p.Traduccion == contactoE.Nacionalidad).SingleOrDefault();
                    if (traduccionPais != null)
                    {
                        var nacionalidad = ctx.DbPais.Where(p => p.LocalizationKey == traduccionPais.ClaveId).SingleOrDefault();
                        if (nacionalidad != null)
                        {
                            cliente.NacionalidadId = nacionalidad.Id;
                        }
                    }

                    if (!cliente.NacionalidadId.HasValue)
                    {
                        contactoE.Mensajes.Add(string.Format(LocalizationProvider.Instance["ServicioExterno.Validacion.SinEntidadRelacionada"], contactoE.Nacionalidad));
                    }
                }

                // Provincia
                if (!String.IsNullOrEmpty(contactoE.Provincia))
                {
                    var traduccionProvincia = ctx.DbPalabrasClaveAplicacionLenguajes.Where(p => p.LenguajeId == paisPorDefecto && p.Traduccion == contactoE.Provincia).SingleOrDefault();
                    if (traduccionProvincia != null)
                    {
                        var provincia = ctx.DbProvincias.Where(p => p.LocalizationKey == traduccionProvincia.ClaveId).SingleOrDefault();
                        if (provincia != null)
                        {
                            cliente.ProvinciaId = provincia.Id;
                        }
                    }

                    if (!cliente.ProvinciaId.HasValue)
                    {
                        contactoE.Mensajes.Add(string.Format(LocalizationProvider.Instance["ServicioExterno.Validacion.SinEntidadRelacionada"], contactoE.Provincia));
                    }
                }

                // Categorias
                if (contactoE.Categorias == null)
                {
                    contactoE.Categorias = new List<string>();
                }

                if (contactoE.Categorias.Count > 0)
                {
                    foreach(string categoriaStr in contactoE.Categorias)
                    {
                        if (!String.IsNullOrEmpty(categoriaStr))
                        {
                            var categoria = ctx.DbCategorias.Where(c => c.EmpresaId == empresaId && c.Nombre == categoriaStr).SingleOrDefault();
                            if (categoria != null)
                            {
                                cliente.Categorias.Add(new MaestroBase { Id = categoria.Id });
                            }
                            else
                            {
                                contactoE.Mensajes.Add(string.Format(LocalizationProvider.Instance["ServicioExterno.Validacion.SinEntidadRelacionada"], categoriaStr));
                            }
                        }
                    }                    
                }
            }

            return cliente;
        }

        public void Dummy()
        {            
        }
    }
}
